package com.xbongbong.parent.parse.data;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.UserHelper;
import com.xbongbong.paas.pojo.dto.AnalysisDataDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.parent.abstracts.AbstractFormDataAnalysisDataHelp;
import com.xbongbong.parent.help.AnalysisTemplateFieldHelp;
import com.xbongbong.pro.domain.entity.LabelEntity;
import com.xbongbong.pro.label.pojo.LabelForDetailUpadatePojo;
import com.xbongbong.pro.label.pojo.LabelPojo;
import com.xbongbong.pro.user.pojo.ReturnUserAndDepartmentPojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ProductCategoryEntity;
import com.xbongbong.saas.enums.NumberTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.help.FormDataAnalysisHelp;
import com.xbongbong.saas.help.ShowFormatHelp;
import com.xbongbong.saas.model.LabelModel;
import com.xbongbong.saas.model.ProductCategoryModel;
import com.xbongbong.saas.service.toolbox.help.AttrDecimalPrecisionHelper;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 获取数据编辑界面回显时解析数据
 * @author: wufeng
 * @date: 2018/12/11 15:17
 * @desrcption:
 */
@Component
public class FormDataUpdateGetAnalysisDataHelp extends AbstractFormDataAnalysisDataHelp {

    @Resource
    private FormDataAnalysisHelp formDataAnalysisHelp;
    @Resource
    private AttrDecimalPrecisionHelper attrDecimalPrecisionHelper;
    @Resource
    private ProductCategoryModel productCategoryModel;
    @Resource
    private LabelModel labelModel;
    @Resource
    private ShowFormatHelp showFormatHelp;
    @Resource
    private AnalysisTemplateFieldHelp analysisTemplateFieldHelp;

    @Override
    public void analysisData(AnalysisDataDTO analysisDataDTO, JSONObject resultJsonObject, Map<String, Object> linkData, Set<Object> linkDataSet) throws XbbException {
        FieldAttrEntity fieldAttrEntity = analysisDataDTO.getFieldAttrEntity();
        String key = analysisDataDTO.getAttr();
        JSONObject objectJsonObject = analysisDataDTO.getDataJsonObject();
        Map<String, UserEntity> userMap = analysisDataDTO.getUserMap();
        Map<String, DepartmentEntity> departmentMap = analysisDataDTO.getDepartmentMap();
        Boolean isOuterLink = analysisDataDTO.getOuterLink();
        String saasAttr = fieldAttrEntity.getSaasAttr();
        boolean rateNumFlag = Objects.equals(ContractEnum.GROSS_PROFIT_RATE.getSaasAttr(), saasAttr)
                || Objects.equals(ContractEnum.CASH_PROFIT_RATE.getSaasAttr(), saasAttr)
                || Objects.equals(ContractEnum.PAY_PERCENT.getSaasAttr(), saasAttr)
                || Objects.equals(SalesOpportunityEnum.GROSS_PROFIT_RATE.getSaasAttr(), saasAttr)
                || Objects.equals(QuotationEnum.GROSS_PROFIT_RATE.getSaasAttr(), saasAttr)
                || Objects.equals(PurchaseEnum.RECEINE_PERCENT.getSaasAttr(), saasAttr);
        if (Objects.equals(fieldAttrEntity.getNumberType(), NumberTypeEnum.RATE.getCode())) {
            rateNumFlag = true;
        }
        // TODO 关于成员和部门回显需要去掉离职人员，现在直接不限，具体如何显示，未解决
        if(FieldTypeEnum.USER.getType().equals(fieldAttrEntity.getFieldType()) || FieldTypeEnum.CREATORID.getType().equals(fieldAttrEntity.getFieldType()) ){
            if(StringUtil.isNotEmpty(objectJsonObject.getString(key))){
                UserEntity userEntity = userMap.get(objectJsonObject.getString(key));
                if (Objects.nonNull(userEntity)) {
                    ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                    BeanUtil.copyProperties(userEntity, returnUserAndDepartmentPojo);
                    returnUserAndDepartmentPojo.setId(userEntity.getUserId());
                    resultJsonObject.put(key, returnUserAndDepartmentPojo);
                } else if (Objects.equals(objectJsonObject.getString(key), StringConstant.NOT_IN_SYSTEM_ID)) {
                    ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                    returnUserAndDepartmentPojo.setName(objectJsonObject.getString(fieldAttrEntity.getLinkedText())+"(离职)");
                    returnUserAndDepartmentPojo.setId(objectJsonObject.getString(key));
                    resultJsonObject.put(key, returnUserAndDepartmentPojo);
                }
            }
        } else if (FieldTypeEnum.USER_GROUP.getType().equals(fieldAttrEntity.getFieldType())
                || FieldTypeEnum.COUSERID.getType().equals(fieldAttrEntity.getFieldType())|| FieldTypeEnum.OWNERID.getType().equals(fieldAttrEntity.getFieldType())) {
            // TODO 协同人和负责人已经在前置解析了，所以这里没有解析，年后统一修改
            List<UserEntity> userList = UserHelper.getUserByKey(key, objectJsonObject, userMap);
            List<ReturnUserAndDepartmentPojo> resultList = new ArrayList<>();
            userList.forEach(item->{
                ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                BeanUtil.copyProperties(item, returnUserAndDepartmentPojo);
                returnUserAndDepartmentPojo.setId(item.getUserId());
                resultList.add(returnUserAndDepartmentPojo);
            });
            resultJsonObject.put(key, resultList);
        } else if(FieldTypeEnum.DEPT.getType().equals(fieldAttrEntity.getFieldType())
                || FieldTypeEnum.DEPARTMENTID.getType().equals(fieldAttrEntity.getFieldType())){
            DepartmentEntity departmentEntity =  departmentMap.get(objectJsonObject.getString(key));
            if(Objects.nonNull(departmentEntity)){
                ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                BeanUtil.copyProperties(departmentEntity, returnUserAndDepartmentPojo);
                resultJsonObject.put(key, returnUserAndDepartmentPojo);
            } else {
                resultJsonObject.remove(key);
            }
        } else if (FieldTypeEnum.DEPT_GROUP.getType().equals(fieldAttrEntity.getFieldType())) {
            List<DepartmentEntity> departmentList = UserHelper.getDepartmentByKey(key, objectJsonObject, departmentMap);
            List<ReturnUserAndDepartmentPojo> resultList = new ArrayList<>();
            departmentList.forEach(item->{
                ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                BeanUtil.copyProperties(item, returnUserAndDepartmentPojo);
                resultList.add(returnUserAndDepartmentPojo);
            });
            resultJsonObject.put(key, resultList);
        } else if (FieldTypeEnum.LINK_DATA.getType().equals(fieldAttrEntity.getFieldType())
                && Objects.nonNull(objectJsonObject.get(key)) && objectJsonObject.get(key) instanceof Number){
            if (Objects.equals(objectJsonObject.get(key), 0)) {
                resultJsonObject.put(key, null);
            } else {
                linkData.put(key, objectJsonObject.get(key));
                if(objectJsonObject.get(key) != null){
                    linkDataSet.add(objectJsonObject.get(key));
                }
                resultJsonObject.put(key, objectJsonObject.get(key));
            }
        } else if (Objects.equals(FieldTypeEnum.LINK_DATA_MULTI.getType(), fieldAttrEntity.getFieldType())
                && Objects.nonNull(objectJsonObject.get(key))
                && (objectJsonObject.get(key) instanceof JSONArray || objectJsonObject.get(key) instanceof ArrayList || objectJsonObject.get(key) instanceof List)) {
            JSONArray linkDataArray = objectJsonObject.getJSONArray(key);
            if (CollectionsUtil.isEmpty(linkDataArray)) {
                resultJsonObject.put(key, null);
            } else {
                linkData.put(key, objectJsonObject.get(key));
                linkDataSet.addAll(linkDataArray);
                resultJsonObject.put(key, objectJsonObject.get(key));
            }
        } else if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.COMBO.getType())
                || Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.RADIO_GROUP.getType())) {
            formDataAnalysisHelp.analysisComboWithColor(objectJsonObject, resultJsonObject, fieldAttrEntity, analysisDataDTO.getCorpid());
        } else if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.COMBO_CHECK.getType())
                || Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.CHECKBOX_GROUP.getType())) {
            formDataAnalysisHelp.analysisComboReturnStrWithColor(objectJsonObject, resultJsonObject, fieldAttrEntity);
        } else if (FieldTypeEnum.LINK_BUSINESS_SINGLE.getType().equals(fieldAttrEntity.getFieldType())) {
            // saas关联业务的特殊逻辑
            if (Objects.nonNull(objectJsonObject.get(key)) && !(objectJsonObject.get(key) instanceof List)) {
                showFormatHelp.formatListBusiness4ShowBase(resultJsonObject, fieldAttrEntity.getAttr(), fieldAttrEntity.getLinkedText(), fieldAttrEntity.getFieldType(), fieldAttrEntity.getLinkedType(), analysisDataDTO.getBusinessType(), analysisDataDTO.getCorpid());
            } else {
                formDataAnalysisHelp.saasAnalysisData(analysisDataDTO, key, objectJsonObject, resultJsonObject);
            }
        } else if(FieldTypeEnum.NUM.getType().equals(fieldAttrEntity.getFieldType()) && objectJsonObject.get(key) instanceof Number) {
            // 小数精度
            Double value;
            try {
                value = objectJsonObject.getDoubleValue(key);
            } catch (JSONException e) {
                value = 0D;
            }
            // 前端由于详情页在渲染上子表单没有做处理，采用了详情用用编辑的模式，导致了这种辣鸡代码去兼容外链且是百分比的情况，后续安排人去改进一下
            Integer accuracy = fieldAttrEntity.getAccuracy();
            if ( isOuterLink && rateNumFlag) {
                accuracy = accuracy + 2;
                fieldAttrEntity.setAccuracy(accuracy);
            }
            resultJsonObject.put(key, attrDecimalPrecisionHelper.formatPrecisionWithIntegerOnly(value, fieldAttrEntity));
        } else if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.UPLOAD.getType())) {
            resultJsonObject.put(key, formDataAnalysisHelp.analysisAttachmentList(objectJsonObject.getString(key)));
        } else if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.LABEL.getType())) {
            analasisLabel(analysisDataDTO, key, objectJsonObject, resultJsonObject );
        } else if (Objects.isNull(analysisDataDTO.getIsProcess()) && Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.ACCOUNT_PERIOD.getType())) {
            String receivablePeriod = resultJsonObject.getString(key);
            JSONObject returnReceivablePeriodJson = JSONObject.parseObject(receivablePeriod);
            resultJsonObject.put(key,returnReceivablePeriodJson);
        } else if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.AREA.getType())) {
            analysisArea(analysisDataDTO, resultJsonObject, key, objectJsonObject);
        } else if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.PURCHASEABLE_GOODS.getType())) {
            JSONArray goodsArr = objectJsonObject.getJSONArray(key);
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("idIn", goodsArr);
            params.put(StringConstant.CORPID, analysisDataDTO.getCorpid());
            params.put(StringConstant.DEL, BasicConstant.ZERO);
            List<ProductCategoryEntity> productCategoryEntityList = productCategoryModel.findEntitys(params);
            List<Object> resultList = new ArrayList<>(productCategoryEntityList.size() << 2);
            productCategoryEntityList.forEach(i -> {
                Map<String, Object> resultMap = new HashMap<>(2);
                resultMap.put("id", i.getId());
                resultMap.put("name", i.getName());
                resultList.add(resultMap);
            });
            resultJsonObject.put(key, resultList);
        } else if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.STAGE_THRUSTER.getType())) {
            formDataAnalysisHelp.analysisStageJsonObject(analysisDataDTO, objectJsonObject, resultJsonObject, fieldAttrEntity);
        } else if(Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.TEMPLATE_FIELD.getType())){
            analysisTemplateFieldHelp.analysisTemplateField(analysisDataDTO.getCorpid(),resultJsonObject, fieldAttrEntity.getAttr());
        } else {
            resultJsonObject.put(key, objectJsonObject.get(key));
            // 审批兼容 25926 影响了地址字段，区分下
            if (Objects.equals(fieldAttrEntity.getIsRedundant(), 1) && (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.TEXT.getType()) || Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.TEXTAREA.getType()))
                    && objectJsonObject.get(key) instanceof Map && Objects.nonNull(analysisDataDTO.getIsProcess()) && analysisDataDTO.getIsProcess()) {
                resultJsonObject.put(key, null);
            }
        }
    }
    /**
     * 处理标签展示
     * @param analysisDataDTO
     * @param key
     * @param objectJsonObject
     * @param resultJsonObject
     */
    private void analasisLabel(AnalysisDataDTO analysisDataDTO, String key, JSONObject objectJsonObject, JSONObject resultJsonObject) {
        JSONArray jsonArray = objectJsonObject.getJSONArray(key);
        if(Objects.nonNull(jsonArray) && CollectionsUtil.isNotEmpty(jsonArray)){
            List<Long> longs = new ArrayList<>();
            try {
                List<LabelPojo> labelPojos = JSON.parseArray(jsonArray.toJSONString(), LabelPojo.class);
                for (LabelPojo item : labelPojos) {
                    longs.add(item.getId());
                }
            } catch (Exception e) {
                 longs = JSON.parseArray(jsonArray.toJSONString(), Long.class);
            }
            List<LabelForDetailUpadatePojo> pojoList = new ArrayList<>();
            if (CollectionsUtil.isNotEmpty(longs)){
                List<LabelEntity> labelEntities = labelModel.getByLabelIds(longs, analysisDataDTO.getCorpid());
                labelEntities.forEach(item -> {
                    LabelForDetailUpadatePojo labelForDetailUpadatePojo= new LabelForDetailUpadatePojo();
                    labelForDetailUpadatePojo.setId(item.getId());
                    labelForDetailUpadatePojo.setName(item.getName());
                    labelForDetailUpadatePojo.setColor(item.getColor());
                    pojoList.add(labelForDetailUpadatePojo);
                });
            }
            resultJsonObject.put(key, pojoList);
        }
    }

    @Override
    protected void analysisNotExistField(String attr, JSONObject data, JSONObject resultData, Map<String, UserEntity> userMap, Integer saasMark) {
        if (Objects.equals(attr, FieldTypeEnum.OWNERID.getAlias()) && data.get(attr) instanceof List) {
            List<UserEntity> userList = UserHelper.getUserByKey(attr, data, userMap);
            List<ReturnUserAndDepartmentPojo> resultList = new ArrayList<>();
            userList.forEach(item->{
                ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                BeanUtil.copyProperties(item, returnUserAndDepartmentPojo);
                returnUserAndDepartmentPojo.setId(item.getUserId());
                resultList.add(returnUserAndDepartmentPojo);
            });
            resultData.put(attr, resultList);
        }
    }
}
